Skip to content

Conversation

@joefarebrother
Copy link
Contributor

Adds remote flow sources for the python-socketio library.

@joefarebrother joefarebrother changed the title Python: Add models for socketio [Draft] Python: Add models for socketio Nov 25, 2025
@joefarebrother joefarebrother marked this pull request as ready for review November 26, 2025 11:39
@joefarebrother joefarebrother requested a review from a team as a code owner November 26, 2025 11:39
Copilot AI review requested due to automatic review settings November 26, 2025 11:39
@joefarebrother joefarebrother changed the title [Draft] Python: Add models for socketio Python: Add models for socketio Nov 26, 2025
Copilot finished reviewing on behalf of joefarebrother November 26, 2025 11:42
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for the python-socketio library by modeling remote flow sources and request handlers. The implementation enables CodeQL to track tainted data flowing through Socket.IO event handlers and callbacks.

Key Changes

  • Added comprehensive models for python-socketio Server, AsyncServer, Namespace, and AsyncNamespace classes
  • Identified Socket.IO event handlers and callbacks as request handlers with appropriate routed parameters
  • Modeled the return value of call() methods as remote flow sources

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
python/ql/lib/semmle/python/frameworks/Socketio.qll Core implementation providing models for Socket.IO servers, event handlers, callbacks, and remote flow sources
python/ql/lib/semmle/python/Frameworks.qll Added import for the new Socketio module in alphabetical order
python/ql/test/library-tests/frameworks/socketio/test.py Test file covering various Socket.IO event handler patterns including decorators and lambda handlers
python/ql/test/library-tests/frameworks/socketio/taint_test.py Comprehensive taint tracking test covering both sync and async Socket.IO patterns, namespaces, and callbacks
python/ql/test/library-tests/frameworks/socketio/InlineTaintTest.ql Query file for inline taint testing
python/ql/test/library-tests/frameworks/socketio/InlineTaintTest.expected Expected test results for inline taint tests
python/ql/test/library-tests/frameworks/socketio/ConceptsTest.ql Query file for concepts testing
python/ql/test/library-tests/frameworks/socketio/ConceptsTest.expected Expected test results for concepts tests (empty, indicating no failures expected)
python/ql/lib/change-notes/2025-11-26-socketio.md Release note documenting the addition of remote flow sources for python-socketio

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

ensure_tainted(data) # $ tainted
res = sio.call("e1", sid=sid)
ensure_tainted(res) # $ tainted
sio.emit("e2", "hi", to=sid, callback=lambda x: ensure_tainted(x)) # $ tainted $ requestHandler routedParameter=x
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This 'lambda' is just a simple wrapper around a callable object. Use that object directly.

Copilot uses AI. Check for mistakes.
res = sio.call("e1", sid=sid)
ensure_tainted(res) # $ tainted
sio.emit("e2", "hi", to=sid, callback=lambda x: ensure_tainted(x)) # $ tainted $ requestHandler routedParameter=x
sio.send("hi", to=sid, callback=lambda x: ensure_tainted(x)) # $ tainted $ requestHandler routedParameter=x
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This 'lambda' is just a simple wrapper around a callable object. Use that object directly.

Suggested change
sio.send("hi", to=sid, callback=lambda x: ensure_tainted(x)) # $ tainted $ requestHandler routedParameter=x
sio.send("hi", to=sid, callback=ensure_tainted) # $ tainted $ requestHandler routedParameter=x

Copilot uses AI. Check for mistakes.
ensure_tainted(data) # $ tainted
res = self.call("e1", sid=sid)
ensure_tainted(res) # $ tainted
self.emit("e2", "hi", to=sid, callback=lambda x: ensure_tainted(x)) # $ tainted $ requestHandler routedParameter=x
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This 'lambda' is just a simple wrapper around a callable object. Use that object directly.

Copilot uses AI. Check for mistakes.
res = self.call("e1", sid=sid)
ensure_tainted(res) # $ tainted
self.emit("e2", "hi", to=sid, callback=lambda x: ensure_tainted(x)) # $ tainted $ requestHandler routedParameter=x
self.send("hi", to=sid, callback=lambda x: ensure_tainted(x)) # $ tainted $ requestHandler routedParameter=x
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This 'lambda' is just a simple wrapper around a callable object. Use that object directly.

Suggested change
self.send("hi", to=sid, callback=lambda x: ensure_tainted(x)) # $ tainted $ requestHandler routedParameter=x
self.send("hi", to=sid, callback=ensure_tainted) # $ tainted $ requestHandler routedParameter=x

Copilot uses AI. Check for mistakes.
ensure_tainted(data) # $ tainted
res = await asio.call("e1", sid=sid)
ensure_tainted(res) # $ tainted
await asio.emit("e2", "hi", to=sid, callback=lambda x: ensure_tainted(x)) # $ tainted $ requestHandler routedParameter=x
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This 'lambda' is just a simple wrapper around a callable object. Use that object directly.

Copilot uses AI. Check for mistakes.
res = await asio.call("e1", sid=sid)
ensure_tainted(res) # $ tainted
await asio.emit("e2", "hi", to=sid, callback=lambda x: ensure_tainted(x)) # $ tainted $ requestHandler routedParameter=x
await asio.send("hi", to=sid, callback=lambda x: ensure_tainted(x)) # $ tainted $ requestHandler routedParameter=x
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This 'lambda' is just a simple wrapper around a callable object. Use that object directly.

Suggested change
await asio.send("hi", to=sid, callback=lambda x: ensure_tainted(x)) # $ tainted $ requestHandler routedParameter=x
await asio.send("hi", to=sid, callback=ensure_tainted) # $ tainted $ requestHandler routedParameter=x

Copilot uses AI. Check for mistakes.
ensure_tainted(data) # $ tainted
res = await self.call("e1", sid=sid)
ensure_tainted(res) # $ tainted
await self.emit("e2", "hi", to=sid, callback=lambda x: ensure_tainted(x)) # $ tainted $ requestHandler routedParameter=x
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This 'lambda' is just a simple wrapper around a callable object. Use that object directly.

Suggested change
await self.emit("e2", "hi", to=sid, callback=lambda x: ensure_tainted(x)) # $ tainted $ requestHandler routedParameter=x
await self.emit("e2", "hi", to=sid, callback=ensure_tainted) # $ tainted $ requestHandler routedParameter=x

Copilot uses AI. Check for mistakes.
res = await self.call("e1", sid=sid)
ensure_tainted(res) # $ tainted
await self.emit("e2", "hi", to=sid, callback=lambda x: ensure_tainted(x)) # $ tainted $ requestHandler routedParameter=x
await self.send("hi", to=sid, callback=lambda x: ensure_tainted(x)) # $ tainted $ requestHandler routedParameter=x
Copy link

Copilot AI Nov 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This 'lambda' is just a simple wrapper around a callable object. Use that object directly.

Suggested change
await self.send("hi", to=sid, callback=lambda x: ensure_tainted(x)) # $ tainted $ requestHandler routedParameter=x
await self.send("hi", to=sid, callback=ensure_tainted) # $ tainted $ requestHandler routedParameter=x

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant